Repository navigation
feat: add per-provider additional scan folders (#177) - #187
Conversation
|
Thanks @Borisserz — a lot of surface handled carefully. I checked the parts that matter rather than reading them:
Blocking items A/B/C from the #162 review and recommendations 1–4 are all in. 1. Rebase — and one part of it is not mechanical
#182 is the one to watch. It landed multi-root discovery for Antigravity: static var defaultRoots: [URL] {
[ ".gemini/antigravity/conversations", // 2.0 / Core
".gemini/antigravity-cli/conversations", // CLI
".gemini/antigravity-ide/conversations" ] // IDE
}
static var defaultRoot: URL { defaultRoots[0] }
defaults: [home.appendingPathComponent(".gemini/antigravity-cli/conversations")]That is now 2. The tests will not tell you if you miss itI checked what would catch it. Nothing does:
Nothing calls 3.
|
Logs outside the built-in paths were a silent undercount for every provider except Claude. Store one list per provider so parsers never share folders, and only add custom roots — never evict a curated default.
…n#177) resolvedRoots hardcoded the CLI path, which is defaultRoots[1] after chattymin#182, so a no-root scan dropped 2.0/Core and IDE stores. Codex custom roots had the same class of hole against archived_sessions (chattymin#181).
5705c3f to
0a7d134
Compare
|
Rebased onto current
Credit for the feature, the No French strings; #185 can pick them up on rebase.
|
|
Thank you for your contribution! |
Brings in upstream features and integrates them with the fork's iOS/OpenCode Go work: - Antigravity 2.0 / IDE official rate-limit tracking (chattymin#210, chattymin#219, chattymin#220) - French (fr) UI language (chattymin#185) — added fr strings to fork-only labels - Per-provider additional scan folders (chattymin#177/chattymin#187) - Account-labeled official limits (chattymin#199), swift.org Swift 6.3 toolchains (chattymin#216), claude-fable-5 pricing (chattymin#198) Conflicts resolved in Localization, UsageStore, PopoverView, and their tests by keeping both the fork's OpenCode Go limits and upstream's Antigravity limits, and by giving fork-only localized labels their French values. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ers (en/ko/ja) Three UI features have shipped since v2.5.1 without an image: pinning a representative Pokémon (#158), official rate limits for Antigravity (#210), and per-provider additional scan folders (#187). Per-provider scan folders were not mentioned in the READMEs at all. Adds two screenshots per language for the Antigravity limits panel and the Advanced scan-folder controls, and inserts the Representative Pokémon row into the existing settings shots rather than redrawing them, so every pixel outside the inserted row is byte-identical to the previous asset. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ers (en/ko/ja) (#223) Three UI features have shipped since v2.5.1 without an image: pinning a representative Pokémon (#158), official rate limits for Antigravity (#210), and per-provider additional scan folders (#187). Per-provider scan folders were not mentioned in the READMEs at all. Adds two screenshots per language for the Antigravity limits panel and the Advanced scan-folder controls, and inserts the Representative Pokémon row into the existing settings shots rather than redrawing them, so every pixel outside the inserted row is byte-identical to the previous asset. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ymin#187) * feat: add per-provider additional scan folders (chattymin#177) Logs outside the built-in paths were a silent undercount for every provider except Claude. Store one list per provider so parsers never share folders, and only add custom roots — never evict a curated default. * fix: union custom scan roots onto every Antigravity default (chattymin#177) resolvedRoots hardcoded the CLI path, which is defaultRoots[1] after chattymin#182, so a no-root scan dropped 2.0/Core and IDE stores. Codex custom roots had the same class of hole against archived_sessions (chattymin#181).
…ers (en/ko/ja) (chattymin#223) Three UI features have shipped since v2.5.1 without an image: pinning a representative Pokémon (chattymin#158), official rate limits for Antigravity (chattymin#210), and per-provider additional scan folders (chattymin#187). Per-provider scan folders were not mentioned in the READMEs at all. Adds two screenshots per language for the Antigravity limits panel and the Advanced scan-folder controls, and inserts the Representative Pokémon row into the existing settings shots rather than redrawing them, so every pixel outside the inserted row is byte-identical to the previous asset. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ymin#200) Gemini/Codex estimates ride other subscriptions, so mixing them into the Max multiple inflates it. Settings was writing UserDefaults on every keystroke; match the chattymin#187 draft+commit field.
Summary
Every provider resolves its log location on its own, and only Claude could be pointed somewhere else from inside the app. A relocated Codex / Gemini / Cursor / … directory does not error — the total is just lower, and nothing in the UI says a folder was missed.
This is the generalized form of #162, landed on
mainso it does not wait on that PR. The feature, theCLAUDE_CONFIG_DIRdiagnosis, and defect B all originated in @hannin's #162; this PR takes that review's blocking items and extends the extra-folder list to every provider. Storage is one list per provider (customScanRoots.<id>), not one flat list every reader tries. Gemini'sallowJSONwalk would otherwise ingest Claude.meta.jsonand mis-attribute tokens.Custom roots only add to curated defaults. An ancestor extra (
~,/) is dropped sonormalizedRootscannot fold a hidden default away —jsonlFilesuses.skipsHiddenFiles, and scanning~silently zeros Claude. That is #162-B, baked in here..skipsHiddenFilesis left alone.#162 can rebase onto these keys or close. There is no generic
customScanRootskey, so no migration.Rebased onto current
main. After #182, Antigravity has three default roots (2.0/Core, CLI, IDE).resolvedRootsunions custom extras onto that full list — a CLI-only literal isdefaultRoots[1]and would silently drop the other two editions. Codex custom roots go throughcomputeCodexScanRoots, so archived sessions (#181) stay in the union.Type of change
UI changes
main(#162's Claude-only field is still on its own branch).Checklist
swift buildandswift testpass locallyWhat this takes from the #162 review
Blocking items from the owner review on #162, applied here so they are not re-opened:
L.t(ko, en, ja, es)— four arguments, currentmain.~and/included). Tests actually scan a hidden.claude/projectsjsonl after that.customScanRoots.claude_code(and.codex,.gemini, …), nevercustomScanRoots.Recommendations 1–4: commit on submit / blur, not keystroke; match count off main thread; count after
normalizedRoots; compute functions defaultcustomRootsValue: nil, notUserDefaults.standard.French strings are left to #185 on rebase, per merge order.
Tests
CustomScanRootsTests/AntigravityUsageTests— each branch alone:testAncestorCustomRootDoesNotEvictCuratedDefault/testClaudeAncestorCustomDoesNotZeroJsonlScan— the Add user-configurable additional scan folders with wildcard support #162-B zero-total. Confirmed by scanning a real jsonl under.claude/projects.testRootFilesystemCustomDoesNotEvictCuratedDefault—/is an ancestor of everything;extra + \"/\"is\"//\"so a naive prefix check would walk the whole disk.testEveryRegisteredProviderConsultsItsOwnCustomScanRootsKey— source sweep forstoredValue(for: \"<id>\"), pluscuratedRoots(for:)non-empty for every registered provider (Settings match count).testNoRootScanReadsEveryDefaultRoot— one turn in each of the three Antigravity default relative paths under a fake home;resolvedRoots+entriesmust see all three. Confirmed red against the CLI-only literal (onlyr1).testEntriesWithoutRootsGoesThroughResolvedRoots— production no-root path and the cache actor both callresolvedRoots.testCodexSessionRootsIncludeArchivedSessions— custom-root union must not drop#181's archived root.testCodexCacheKeepsSessionIndexAcrossMultipleRoots— prune after the union, not per root.testCodexCacheFindsParentInASiblingRoot— parent-closure over the union.testSetCustomScanRootsInvalidatesAdditionalProviderCache— OpenCode/Cursor/Copilot/Kiro 30s cache would hide a newly added folder.testSettingsUsesProviderPickerAndCommitsOnSubmit— picker + one list;customScanDraftOwnerIDso a picker click that blurs the field cannot write Claude paths intocustomScanRoots.gemini.Full suite: 760 pass, 10 skipped, 0 failures.
How to verify
Manual: Settings → Advanced → pick a provider whose logs are outside the built-in path → paste that folder → submit or click away. The next refresh should pick those sessions up. Pointing Gemini at a Claude folder must not inflate Gemini. Typing
~must not drop today's Claude total to zero.Closes #177